﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Collections.Specialized;
using System.Windows;

namespace WrWpf.Controls
{
    /// <summary>
    /// there are situations when there is the need to keep track of the elements in a collection.
    /// The class UIElementCollection in the framework and used throughout WPF controls does not 
    /// provide for much control over its members.
    /// </summary>
    /// <example>
    /// protected override UIElementCollection CreateUIElementCollection(FrameworkElement logicalParent)
    /// {
    ///     return new ObservableUIElementCollection(this, logicalParent);
    /// } 
    /// </example>
    public class ObservableUIElementCollection : UIElementCollection, INotifyCollectionChanged
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ObservableUIElementCollection"/> class.
        /// </summary>
        /// <param name="visualParent">The visual parent.</param>
        /// <param name="logicalElement">The logical element.</param>
        public ObservableUIElementCollection(UIElement visualParent, FrameworkElement logicalElement) :
            base(visualParent, logicalElement)
        {
        }


        /// <summary>
        /// Adds the specified element to the <see cref="T:System.Windows.Controls.UIElementCollection"/>.
        /// </summary>
        /// <param name="element">The <see cref="T:System.Windows.UIElement"/> to add.</param>
        /// <returns>The index position of the added element.</returns>
        public override int Add(UIElement element)
        {
            int index = base.Add(element);
            OnCollectionChanged(NotifyCollectionChangedAction.Add, element, index);
            return index;
        }

        /// <summary>
        /// Removes the specified element from a <see cref="T:System.Windows.Controls.UIElementCollection"/>.
        /// </summary>
        /// <param name="element">The element to remove from the collection.</param>
        public override void Remove(UIElement element)
        {
            int index = IndexOf(element);
            base.Remove(element);
            OnCollectionChanged(NotifyCollectionChangedAction.Add, element, index);
        }

        /// <summary>
        /// Raises the <see cref="E:CollectionChanged"/> event.
        /// </summary>
        /// <param name="e">The <see cref="System.Collections.Specialized.NotifyCollectionChangedEventArgs"/> instance containing the event data.</param>
        protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            NotifyCollectionChangedEventHandler collectionChanged = CollectionChanged;

            if (collectionChanged != null)
                collectionChanged(this, e);
        }

        /// <summary>
        /// Called when [collection changed].
        /// </summary>
        /// <param name="action">The action.</param>
        /// <param name="item">The item.</param>
        /// <param name="index">The index.</param>
        void OnCollectionChanged(NotifyCollectionChangedAction action, object item, int index)
        {
            OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, item, index));
        }

        /// <summary>
        /// Occurs when the collection changes.
        /// </summary>
        public event NotifyCollectionChangedEventHandler CollectionChanged;


    }

}
